package com.seuic.hnapps.util;

import android.content.Context;
import android.util.Log;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.gson.Gson;
import com.seuic.hnapps.bean.CardBinInfo_bean;
import com.seuic.hnapps.bean.K_binBean;
import com.solab.enc.DES3;
import com.solab.enc.SMS4;
import com.solab.iso8583.IsoMessage;
import com.solab.iso8583.IsoType;

import java.util.ArrayList;
import java.util.List;

/**
 * @author Administrator
 * 终端签到
 */
public class RWKInterface {
    private static final Logger log = LoggerFactory.getLogger(RWKInterface.class);

    public IsoMessage packRequest(String transn, String TermSerial) {

        IsoMessage msg = new IsoMessage();

        msg.setType(0x0820);
        msg.setHeadValue(1, String.valueOf(Constants.ATMP_HEADER_LENGTH), IsoType.BCD, 2);
        msg.setHeadValue(2, Constants.YANTAI_PACKVS, IsoType.ALPHA, 2);
        msg.setHeadValue(3, Constants.YANTAI_TERMVS, IsoType.ALPHA, 8);
        msg.setHeadValue(4, Constants.YANTAI_ENCFLG1, IsoType.ALPHA, 1); // 加密标志。管理类交易不需加密
        msg.setHeadValue(5, Constants.YANTAI_BANKID, IsoType.ALPHA, 8);
        msg.setHeadValue(6, Constants.YANTAI_TERMNO, IsoType.ALPHA, 8);
        msg.setHeadValue(7, "0000", IsoType.ALPHA, 4); // 8583域部分长度，组包时动态填充

        msg.setValue(7, DateUtil.getCurrentTime(DateUtil.M_TIME_PATTERN), IsoType.ALPHA, 10);
        msg.setValue(8, Constants.YANTAI_CHANLENO, IsoType.ALPHA, 2);
        msg.setValue(11, transn, IsoType.ALPHA, 6);
        msg.setValue(41, Constants.YANTAI_TERMNO, IsoType.ALPHA, 8);
        if(Constants.isSM){
            msg.setValue(53, Constants.DEMO_F53, IsoType.ALPHA, 16);
        }
        msg.setValue(70, "003", IsoType.ALPHA, 3);
        //F120 理财信息 终端支持理财相关交易则填写此域
        msg.setValue(120, "QY", IsoType.LLLVAR, 512);

        //F122 终端序列号 需根据自己的设备获取相应的硬盘序列号
//        String pansn = "WDEJCNHX";
        String pansn = TermSerial;
        String tag = "SN";
        String sblen = ServiceCommon.appendZero(pansn.length(), 3);
        String s122 = tag + sblen + pansn;
        msg.setValue(122, s122, IsoType.LLLVAR, 512);

        // F123 卡BIN信息  终端可选支持  用于识别本行卡
        msg.setValue(123, "CB", IsoType.LLLVAR, 512);

        return msg;
    }


    public void unpackReSpone(IsoMessage response, Context context) {
        List<CardBinInfo_bean> beans = new ArrayList<>();
        // 终端需要与后台同步时间
        if (response.getField(17) != null) {
            String f17 = response.getStringValue(17);
            log.debug("把终端本地时间更改为：[{}]", f17);
        }
        // 终端需要保存批次号信息
        if (response.getField(60) != null) {
            String f60 = response.getStringValue(60);
            String batchno = f60.substring(0, 4);
            Constants.YANTAI_BATCHNO = batchno;
        }
        // 保存密钥信息
        if (response.getField(61) != null) {
            String f61 = response.getStringValue(61);

            String tag = f61.substring(0, 2);
            String slen = f61.substring(2, 5);
            String atmpik = f61.substring(5, 37); // PIN 密钥
            String pcheck = f61.substring(37, 45);// PIN 密钥校验值
            String atmmak = f61.substring(45, 77);// MAC 密钥
            String mcheck = f61.substring(77, 85);// MAC 密钥校验值
            String atmtdk = f61.substring(85, 117);// 磁道/报文加密 密钥
            String tcheck = f61.substring(117, 125);// 磁道/报文加密 密钥校验值

//            com.orhanobut.logger.Logger.e(
//                    "atmpik" + atmpik + "\n" +
//                            "pcheck" + pcheck + "\n" +
//                            "atmmak" + atmmak + "\n" +
//                            "mcheck" + mcheck + "\n" +
//                            "atmtdk" + atmtdk + "\n" +
//                            "tcheck" + tcheck
//            );
            /**
             * 得到3把密钥，可直接灌入密码键盘
             */


            /**
             * 以下部分均为本demo后续测试需要   开始.......
             */

            // 取申请主密钥时得到的终端主密钥
            String tmk = Constants.YANTAI_TERMTMK;
            String mpik="",mmak="",mtdk="";
            if(Constants.isSM){
                mpik = SMS4.sms4key(atmpik, tmk, SMS4.DECRYPT);
                String p1 = SMS4.sms4CheckValue(mpik, 8);
                if(!p1.equals(pcheck)){
                    System.out.println("SM4.resp.pik.chekval["+pcheck+"] != locl.pik.chekval=["+p1+"]");
                }else{
                    System.out.println("SM4.pik=["+mpik+"]");
                }

                mmak = SMS4.sms4key(atmmak, tmk, SMS4.DECRYPT);
                String m1 = SMS4.sms4CheckValue(mmak, 8);
                if(!m1.equals(mcheck)){
                    System.out.println("SM4.resp.mak.chekval["+mcheck+"] != locl.mak.chekval=["+m1+"]");
                }else{
                    System.out.println("SM4.mak=["+mmak+"]");
                }

                mtdk = SMS4.sms4key(atmtdk, tmk, SMS4.DECRYPT);
                String t1 = SMS4.sms4CheckValue(mtdk, 8);
                if(!t1.equals(tcheck)){
                    System.out.println("SM4.resp.tdk.chekval["+tcheck+"] != locl.tdk.chekval=["+t1+"]");
                }else{
                    System.out.println("SM4.tdk=["+mtdk+"]");
                }

            }else {
                byte[] out32 = new byte[32];
                DES3.undes3_32_32(atmpik.getBytes(), tmk.getBytes(), out32);
                mpik = new String(out32);
                String p1 = DES3.getCheckKeyVal8(mpik.getBytes());
                if (!p1.equals(pcheck)) {
                    log.error("resp.pik.chekval[" + pcheck + "] != locl.pik.chekval=[" + p1 + "]");
                } else {
                    log.debug("pik=[" + mpik + "]");
                }

                out32 = new byte[32];
                DES3.undes3_32_32(atmmak.getBytes(), tmk.getBytes(), out32);
                mmak = new String(out32);
                String m1 = DES3.getCheckKeyVal8(mmak.getBytes());
                if (!m1.equals(mcheck)) {
                    log.error("resp.mak.chekval[" + mcheck + "] != locl.mak.chekval=[" + m1 + "]");
                } else {
                    log.debug("mak=[" + mmak + "]");
                }

                out32 = new byte[32];
                DES3.undes3_32_32(atmtdk.getBytes(), tmk.getBytes(), out32);
                 mtdk = new String(out32);
                String t1 = DES3.getCheckKeyVal8(mtdk.getBytes());
                if (!t1.equals(tcheck)) {
                    log.error("resp.tdk.chekval[" + tcheck + "] != locl.tdk.chekval=[" + t1 + "]");
                } else {
                    log.debug("tdk=[" + mtdk + "]");
                }
                // 本demo后续测试需要，手工保存起

                /**
                 * 以上部分均为本demo后续测试需要   结束.......
                 */
            }
            com.orhanobut.logger.Logger.e("mpik" + mpik);
            com.orhanobut.logger.Logger.e("mmak" + mmak);
            com.orhanobut.logger.Logger.e("mtdk" + mtdk);
            Constants.YANTAI_PINKEY = mpik;
            Constants.YANTAI_MACKEY = mmak;
            Constants.YANTAI_TDKKEY = mtdk;
        }
        // 保存理财信息   支持理财的终端需本地保存
        if (response.getField(120) != null) {
            String f120 = response.getStringValue(120);
            String snum = f120.substring(2, 5);
            int num = Integer.parseInt(snum);
            String f120p = f120.substring(5);
            String[] pp = f120p.split("[\u007c]");

            for (int i = 0; i < num; i++) {
                String key = pp[i * 2];
                String value = pp[i * 2 + 1];
                if (i == 0) {
                    Constants.DEMO_WLY = key;
                } else {
                    Constants.DEMO_CXY = key;
                }
                com.orhanobut.logger.Logger.e("理财标号=[{" + key + "}] 理财名称=[{" + value + "}]" + i);
            }
        }

        com.orhanobut.logger.Logger.e(response.getField(123) + "");
        // 终端保存本行卡BIN信息
        if (response.getField(123) != null) {
            String f123 = response.getStringValue(123);
            String snum = f123.substring(2, 5);
            int num = Integer.parseInt(snum);
            com.orhanobut.logger.Logger.e(num + "");
            String f123p = f123.substring(5);
            com.orhanobut.logger.Logger.e(f123p);
            List<K_binBean> k_binBeans = new ArrayList<>();
            for (int i = 0; i < num; i++) {
                int len = 0, pos = 0;
                // 卡类型 1-本行卡
                len = 1;
                String selfcard = f123p.substring(pos, pos + len);
                pos += len;
                /**  卡种
                 *  1-借记卡
                 2-贷记卡
                 3-准贷记卡
                 4-预付卡
                 */
                len = 1;
                String cardtype = f123p.substring(pos, pos + len);
                pos += len;
                // 卡BIN长度
                len = 2;
                String binlen = f123p.substring(pos, pos + len);
                pos += len;
                // 卡BIN
                len = Integer.parseInt(binlen);
                String cardbin = f123p.substring(pos, pos + len);
                pos += len;
                com.orhanobut.logger.Logger.e("卡类型=[{" + selfcard + "}] 卡种=[{" + cardtype + "}] 卡BIN长度=[{" + binlen + "}] 卡BIN=[{" + cardbin + "}]" + selfcard + cardtype + binlen + cardbin);
                f123p = f123p.substring(pos);
                CardBinInfo_bean cardBinInfo_bean = new CardBinInfo_bean(Integer.parseInt(cardtype), Integer.parseInt(binlen), cardbin);

                beans.add(cardBinInfo_bean);
                K_binBean k_binBean = new K_binBean(binlen, cardbin);
                k_binBeans.add(k_binBean);
                /**
                 * 卡BIN终端保存在卡表信息
                 * 后续交易读取卡号在本地卡表检索，判断是否本行卡
                 * 判断是否接贷记卡
                 *
                 * DEMO测试用，只保存卡种
                 */
                Constants.YANTAI_CARDTYPE = cardtype;
            }
            Gson gson = new Gson();
            String listStr = gson.toJson(beans);
            String kbin = gson.toJson(k_binBeans);
            SpUtils.getSPUtil(context).putString("c_bin_info", listStr);
            //专门存卡bin
            SpUtils.getSPUtil(context).putString("k_bean", kbin);
            com.orhanobut.logger.Logger.e(beans.size() + "");

        }


    }

}
